import * as Cesium from '@cesiumjs';

function ViewerShortcutAction(viewer) {

  const _this = this;

  var scene = viewer.scene;
  var canvas = viewer.canvas;
  canvas.setAttribute('tabindex', '0'); // needed to put focus on the canvas
  canvas.onclick = function() {
    canvas.focus();
  };
  var ellipsoid = scene.globe.ellipsoid;

  const keyCode2Action = {}

  keyCode2Action["S".charCodeAt(0)] = 'moveForward';
  keyCode2Action[107] = 'moveForward'; // +
  keyCode2Action[187] = 'moveForward'; // +=
  keyCode2Action["D".charCodeAt(0)] = 'moveBackward';
  keyCode2Action[109] = 'moveBackward'; // -
  keyCode2Action[189] = 'moveBackward'; // -_
  keyCode2Action["E".charCodeAt(0)] = 'rotateUp';
  // keyCode2Action["X".charCodeAt(0)] = 'rotateDown';
  // keyCode2Action["Z".charCodeAt(0)] = 'rotateDown';
  // keyCode2Action["C".charCodeAt(0)] = 'rotateDown';

  keyCode2Action["F".charCodeAt(0)] = 'rotateRight';
  keyCode2Action["A".charCodeAt(0)] = 'rotateLeft';

  // keyCode2Action["Q".charCodeAt(0)] = 'rotateLeft';
  keyCode2Action[37] = 'rotateLeft'; // Left Arrow
  keyCode2Action["W".charCodeAt(0)] = 'rotateDown';
  keyCode2Action[39] = 'rotateRight'; // Right Arrow
  // keyCode2Action["R".charCodeAt(0)] = 'rotateDown';
  // keyCode2Action["G".charCodeAt(0)] = 'rotateDown';
  keyCode2Action[38] = 'rotateDown'; // Up Arrow
  // keyCode2Action["T".charCodeAt(0)] = 'rotateUp';
  // keyCode2Action["V".charCodeAt(0)] = 'rotateUp';
  keyCode2Action[40] = 'rotateUp'; // Dw Arrow

  keyCode2Action["U".charCodeAt(0)] = 'moveUp';
  keyCode2Action["J".charCodeAt(0)] = 'moveDown';
  keyCode2Action["Y".charCodeAt(0)] = 'moveRight';
  keyCode2Action["I".charCodeAt(0)] = 'moveLeft';

  const actionRates = {
    rotateLeft: 0.005,
    rotateRight: 0.005,
    rotateDown: 0.005,
    rotateUp: 0.005,
  }

  _this.currentAction = null;

  function keydownEventListener(e) {
    _this.currentAction = keyCode2Action[e.keyCode];
  }

  function keyupEventListener(e) {
    _this.currentAction = null;
  }

  var startMousePosition;
  var mousePosition;
  var flags = {
    looking: false,
  };

  viewer.clock.onTick.addEventListener(function(clock) {
    var camera = viewer.camera;

    if (flags.looking) {
      var width = canvas.clientWidth;
      var height = canvas.clientHeight;
      // Coordinate (0.0, 0.0) will be where the mouse was clicked.
      var x = (mousePosition.x - startMousePosition.x) / width;
      var y = (mousePosition.y - startMousePosition.y) / height;

      var lookFactor = 0.05;
      camera.rotateRight(x * lookFactor);
      camera.rotateUp(y * lookFactor);
      return;
    }

    // Change movement speed based on the distance of the camera to the surface of the ellipsoid.
    var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
    var moveRate = cameraHeight / 100.0;

    const currentAction = _this.currentAction;
    if (currentAction) {
      camera[currentAction](actionRates[currentAction] || moveRate);
    }
  });

  this.enableShortcut = function(enable) {
    // disable the default event handlers
    scene.screenSpaceCameraController.enableRotate = !enable;
    scene.screenSpaceCameraController.enableTranslate = !enable;
    scene.screenSpaceCameraController.enableZoom = !enable;
    scene.screenSpaceCameraController.enableTilt = !enable;
    scene.screenSpaceCameraController.enableLook = !enable;

    if (enable) {
      this.handler = (this.handler || new Cesium.ScreenSpaceEventHandler(canvas));

      this.handler.setInputAction(function(movement) {
        flags.looking = true;
        mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
      }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

      this.handler.setInputAction(function(movement) {
        mousePosition = movement.endPosition;
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      this.handler.setInputAction(function(position) {
        flags.looking = false;
      }, Cesium.ScreenSpaceEventType.LEFT_UP);

      canvas.addEventListener(
        'keydown',
        keydownEventListener,
        false
      );
      canvas.addEventListener(
        'keyup',
        keyupEventListener,
        false
      );
    } else {
      this.destroy()
    }
    return enable
  }

  this.destroy = function() {
    canvas.removeEventListener('keydown', keydownEventListener);
    canvas.removeEventListener('keyup', keyupEventListener);
    this.handler && this.handler.destroy()
    this.handler = null
  }
}

export default ViewerShortcutAction;
